function guid() {
    var S4 = function () {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    };
    return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}

function gcFlowDesinger() {

}

gcFlowDesinger.prototype.addNode = function (node) {
    var nodeType = this.settings.nodes.find(function (item) {
        return item.type == node.nodeType;
    });
    $desingerNode = $(nodeType.template.replace(/{title}/g, nodeType.name));
    $desingerNode.css('position', 'absolute');
    $desingerNode.css('top', y);
    $desingerNode.css('left', x);
    $desingerNode.attr('id', node.nodeId);
    $(this.container).append($desingerNode);

    var anchors = ["TopCenter", "BottomCenter", "LeftMiddle", "RightMiddle"];
    var point = {
        endpoint: "Dot",
        paintStyle: {
            stroke: "#7AB02C",
            fill: "transparent",
            radius: 7,
            strokeWidth: 1
        },
        maxConnections: -1,
        isTarget: true,
        isSource: true,
        connector: [this.settings.line.lineType, this.settings.line.lineOptions],
        connectorStyle: this.settings.line.style,
        hoverPaintStyle: {
            fill: "#216477",
            stroke: "#216477"
        },
        connectorHoverStyle: this.settings.line.hoverStyle,
        dragOptions: {},
        overlays: [
            ["Label", {
                location: [0.5, 1.5],
                label: "Drag",
                visible: false
            }]
        ]
    };

    for (var i = 0; i < anchors.length; i++) {
        var pointId = node.nodeId + anchors[i];
        this.jsplumb.addEndpoint(node.nodeId, point, {
            anchor: anchors[i], uuid: pointId
        });
    }

};

gcFlowDesinger.prototype.addLine = function (line) {
    this.jsplumb.connect({
        uuids: [line.sourcePointId, line.targetPointId],
        editable: true
    })
}

gcFlowDesinger.prototype.getAllNodes = function () {

}

gcFlowDesinger.prototype.getAllLines = function () {

}

gcFlowDesinger.prototype.init = function (settings, $toolbar, $container) {
    if (!settings) {
        console.log('setting can not be null!');
    }
    return;
    if (!settings.nodes || !settings.nodes.length) {
        console.log('setting.nodes 节点类型至少要有一个!');
        return;
    }
    if (!settings.line) {
        console.log('setting.line can not be null!');
        return;
    }
    if (!$toolbar) {
        console.log('工具栏容器不能为空!');
        return;
    }
    if (!$container) {
        console.log('设计器容器不能为空!');
        return;
    }
    this.settings = settings;
    this.toolbar = $toolbar;
    this.container = $container;

    var _this = this;

    $container.css('position', 'relative');
    $container.bind('drop', function (event) {
        var x = event.offsetX;
        var y = event.offsetY;
        var nodeType = event.dataTransfer.setData("nodeType", nodeType);

        _this.addNode({
            nodeId: guid(),
            nodeType: nodeType.type,
            x: x,
            y: y,
            title: nodeType.name
        });
    });
    $container.bind('dragover', function (event) {
        event.preventDefault();
    });

    for (var i = 0; i < settings.nodes.length; i++) {
        var nodeType = settings.nodes[i];

        $toolbarNode = $(nodeType.toolbarTemplate);
        $toolbarNode.bind('dragstart', function (event) {
            event.dataTransfer.setData("nodeType", nodeType);
        });

        $toolbar.append($toolbarNode);
    }


    this.jsplumb = jsPlumb.getInstance({
        ConnectionOverlays: [
            ["Arrow", {
                location: 1,
                visible: true,
                width: 11,
                length: 11
            }],
            ["Label", {
                location: 0.1
            }]
        ],
        Container: $container.attr('id')
    });
}